home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / PRGMANIA / VERSION1.5 / GEMMENU.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-29  |  15.2 KB  |  420 lines

  1. /*************************************************************************
  2.  * Gestion des menus en fenêtres                                         *
  3.  *************************************************************************/
  4.  
  5. #include "WindGem.h"
  6. #include "winproto.h"
  7.  
  8. /* Fonctions privées à GemMenu.C */
  9. static void wmenu_tnormal (Wind *wind, int title, int flag);
  10. static int boite (Wind *wind, int ob);
  11.  
  12. /*-----------------------------------------------------------------------*
  13.  * Ajoute un menu dans une fenêtre quelconque avec affichage éventuel.   *
  14.  *-----------------------------------------------------------------------*/
  15. void AjouteMenu (int numObj, int menu, int mode, void (*wmenu)(int opt))
  16. {
  17.     Wind *wind;
  18.     OBJECT *win_menu;
  19.     
  20.     wind = ObjListe(numObj);
  21.  
  22.     if (wind != WIND_NULL && menu > 0 && wind->adr_wmenu == (OBJECT *)NULL)
  23.     {
  24.         /* Récupère l'adresse de l'objet menu */
  25.         rsrc_gaddr (R_TREE, menu, &win_menu);        /* Demander adresse menu   */
  26.         /* Fonction de gestion du menu */
  27.         if (wind->adr_wmenu = copy_tree(win_menu));
  28.         {
  29.             wind->wmenu = wmenu;
  30.   
  31.         /* Pas de trame, cadre 1 pixel vers l'extérieur */
  32.            wind->adr_wmenu[BARMENU].ob_spec.index = 0xFF1101L;
  33.  
  34.             if (wind->type == WTYPFORM)
  35.                 wind->Hpos += wind->adr_wmenu[BARTITLE].ob_height;
  36.  
  37.             RecaleWind(wind);
  38.  
  39.             if (mode == REDRAW && wind->handle != BLANK)
  40.                 wind_set(wind->handle, WF_CURRXYWH, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos);
  41.     }
  42.     }
  43. }
  44.  
  45. /*-----------------------------------------------------------------------*
  46.  * Enlève un menu dans une fenêtre quelconque avec affichage éventuel.   *
  47.  *-----------------------------------------------------------------------*/
  48. void EnleveMenu (int numObj, int mode)
  49. {
  50.     Wind *wind;
  51.     
  52.     wind = ObjListe(numObj);
  53.  
  54.     if (wind != WIND_NULL && wind->adr_wmenu != (OBJECT *)NULL)
  55.     {
  56.         if (wind->type == WTYPFORM)
  57.             wind->Hpos -= wind->adr_wmenu[BARTITLE].ob_height;
  58.  
  59.         free(wind->adr_wmenu);
  60.         wind->adr_wmenu = (OBJECT *)NULL;
  61.         wind->wmenu = (void *)NULL;
  62.  
  63.         RecaleWind (wind);
  64.         
  65.         if (mode == REDRAW && wind->handle != BLANK)
  66.         {
  67.             wind_set(wind->handle, WF_CURRXYWH, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos);
  68.             EnvoiRedraw(wind->handle, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos);
  69.         }
  70.     }
  71. }
  72.  
  73. /*-----------------------------------------------------------------------*
  74.  * Check ou dé-check une option du menu.                                 *
  75.  *-----------------------------------------------------------------------*/
  76. void wmenu_icheck (int arbre, int obj, int etat)
  77. {
  78.     Wind *wind;
  79.     
  80.     wind = ObjListe(arbre);
  81.     if (wind != WIND_NULL && wind->adr_wmenu != (OBJECT *)NULL)
  82.         menu_icheck (wind->adr_wmenu, obj, etat);
  83. }
  84.  
  85. static int mx, my, mk;
  86. /*-----------------------------------------------------------------------*
  87.  * inverse un titre de menu en fenêtre.                                  *
  88.  *-----------------------------------------------------------------------*/
  89. static void wmenu_tnormal (Wind *wind, int title, int flag)
  90. {
  91.     int x, y;
  92.     int xw, yw, ww, hw;
  93.  
  94.   wind_get (wind->handle, WF_WORKXYWH, &xw, &yw, &ww, &hw);
  95.   if (! flag)
  96.       (wind->adr_wmenu)[title].ob_state |= SELECTED;
  97.   else
  98.       (wind->adr_wmenu)[title].ob_state &= ~SELECTED;
  99.   objc_offset ((wind->adr_wmenu), title, &x, &y);
  100.  
  101.     objc_draw (wind->adr_wmenu, BARMENU, MAX_DEPTH, x, y, 
  102.                          min(ww - (wind->adr_wmenu)[title].ob_x - 16, (wind->adr_wmenu)[title].ob_width),
  103.                          (wind->adr_wmenu)[title].ob_height);
  104. }
  105.  
  106. /*-----------------------------------------------------------------------*
  107.  * Boîte correspondant à un titre.                                       *
  108.  *-----------------------------------------------------------------------*/
  109. static int boite (Wind *wind, int ob)
  110. {
  111.     register int b, i;
  112.  
  113.   b= (wind->adr_wmenu)->ob_tail;        /* Fond des boîtes */
  114.   b= (wind->adr_wmenu)[b].ob_head;      /* 1° boîte */
  115.   for (i = 3 ; i < ob ; i++)
  116.          b= (wind->adr_wmenu)[b].ob_next;        /* Boîte suivante */
  117.  
  118.   return b;
  119. }
  120.  
  121. /*-----------------------------------------------------------------------*
  122.  * Gestion du menu en fenêtre.                                           *
  123.  *-----------------------------------------------------------------------*/
  124. void menu_wind (Wind *wind, int ob)
  125. {
  126.     int xw, yw, ww, hw, etat;
  127.     int x, y, w, h, dummy, bmenu;
  128.     int obj, old_obj = -1, tit, evnt, mess[8], sortie = 0;
  129.   MFDB img;
  130.  
  131.   wind_update (BEG_MCTRL);            /* Bloquer menu principal */
  132.   wind_get (wind->handle, WF_WORKXYWH, &xw, &yw, &ww, &hw);
  133.  
  134.   while (Sys->mousek) /* Attente relacher bouton souris */
  135.         graf_mkstate (&dummy, &dummy, &(Sys->mousek), &dummy);
  136.  
  137.   /* Sélectionner titre */
  138.   wmenu_tnormal (wind, ob, 0); 
  139.  
  140.   /* Chercher boîte de menu correspondante */
  141.   bmenu = boite (wind, ob);
  142.  
  143.     /* Largeur et hauteur de la boîte */
  144.   w = (wind->adr_wmenu)[bmenu].ob_width;
  145.   h = (wind->adr_wmenu)[bmenu].ob_height;
  146.  
  147.   /* Replacer la boîte sous le titre */
  148.   (wind->adr_wmenu)[bmenu].ob_x = (wind->adr_wmenu)[ob].ob_x + 16;
  149.   (wind->adr_wmenu)[bmenu].ob_y = 0;
  150.   objc_offset ((wind->adr_wmenu), bmenu, &x, &y);
  151.  
  152.   /* Corriger la position si on sort du bureau */
  153.   if (x + w > Sys->Xdesk + Sys->Wdesk - 5)
  154.   {
  155.     (wind->adr_wmenu)[bmenu].ob_x -= ((x + w) - (Sys->Xdesk + Sys->Wdesk) + 5);
  156.       objc_offset ((wind->adr_wmenu), bmenu, &x, &y);
  157.   }
  158.   if (y + h > Sys->Ydesk + Sys->Hdesk - 5)
  159.   {
  160.     (wind->adr_wmenu)[bmenu].ob_y -= ((y + h) - (Sys->Ydesk + Sys->Hdesk) + 5);
  161.       objc_offset ((wind->adr_wmenu), bmenu, &x, &y);
  162.   }
  163.   /* Copier l'image du fond */
  164.   get_bkgr (x, y, w, h, &img);
  165.   objc_draw ((wind->adr_wmenu), bmenu, MAX_DEPTH, x - 3, y - 3, w + 6, h + 6);
  166.     tit = ob;
  167.  
  168.     do  /* BOUCLE D'ATTENTE */
  169.   {
  170.       evnt = evnt_multi (MU_BUTTON | MU_TIMER,
  171.                        1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  172.                        mess, 10, 0, &mx, &my, &mk, &dummy, &dummy, &dummy);
  173.  
  174.     if (evnt & MU_BUTTON)    /* Si on clique */
  175.     {
  176.         /* Virer le menu déroulé */
  177.         put_bkgr (x, y, w, h, &img);
  178.  
  179.       /* Attend que le bouton de la souris soit relâché */
  180.       while (mk)
  181.             graf_mkstate (&dummy, &dummy, &mk, &dummy);
  182.  
  183.       /* On peut sortir */
  184.       sortie = 1;
  185.     }
  186.     else if (evnt == MU_TIMER)    /* S'il ne s'est "rien" passé */
  187.     {
  188.             /* Position actuelle de la sourie */
  189.         graf_mkstate (&mx, &my, &dummy, &dummy);
  190.  
  191.             /* Chercher objet pointé dans le menu */
  192.       obj = objc_find ((wind->adr_wmenu), bmenu, MAX_DEPTH, mx, my);
  193.       if (obj == -1)    /* S'il n'y en a pas */
  194.       {    /* Chercher titre pointé dans la barre */
  195.         obj = objc_find ((wind->adr_wmenu), BARTITLE, MAX_DEPTH, mx, my);
  196.       }
  197.  
  198.             /* Si on est sur un titre et dans la fenêtre */
  199.       if (((wind->adr_wmenu)[obj].ob_type == G_TITLE) && (mx < (xw + ww)))
  200.       {
  201.           if (old_obj != -1) /* S'il on était avant sur une option */
  202.         {    /* La désélectionner */
  203.             etat = (wind->adr_wmenu)[old_obj].ob_state & ~SELECTED; 
  204.           objc_change ((wind->adr_wmenu), old_obj, 0, x, y, w, h, etat, 1);
  205.         }
  206.         if (obj != tit)    /* Si on a changé de titre */
  207.         {
  208.               put_bkgr (x, y, w, h, &img);                    /* Effacer l'ancien menu */
  209.           wmenu_tnormal (wind, tit, 1);                   /* Désélectionner l'ancien */
  210.           tit = obj;                                      /* Enregistrer nouveau titre courant */
  211.           wmenu_tnormal (wind, tit, 0);                   /* Sélectionner titre */
  212.           bmenu = boite (wind, tit);                      /* Menu correspondant */
  213.           w = (wind->adr_wmenu)[bmenu].ob_width;  /* Largeur du menu */
  214.           h = (wind->adr_wmenu)[bmenu].ob_height; /* Hauteur du menu */
  215.           (wind->adr_wmenu)[bmenu].ob_x = (wind->adr_wmenu)[tit].ob_x + 16;  /* Le positionner sous son titre */
  216.           (wind->adr_wmenu)[bmenu].ob_y = 0;
  217.           objc_offset ((wind->adr_wmenu), bmenu, &x, &y);
  218.           if (x + w > Sys->Xdesk + Sys->Wdesk - 5)    /* Correction s'il sort du bureau */
  219.           {
  220.                 (wind->adr_wmenu)[bmenu].ob_x -= ((x + w) - (Sys->Xdesk + Sys->Wdesk) + 5);
  221.             objc_offset ((wind->adr_wmenu), bmenu, &x, &y);
  222.           }
  223.           if (y + h > Sys->Ydesk + Sys->Hdesk - 5)
  224.           {
  225.                 (wind->adr_wmenu)[bmenu].ob_y -= ((y + h) - (Sys->Ydesk + Sys->Hdesk) + 5);
  226.             objc_offset ((wind->adr_wmenu), bmenu, &x, &y);
  227.           }
  228.           get_bkgr (x, y, w, h, &img);
  229.           objc_draw ((wind->adr_wmenu), bmenu, MAX_DEPTH, x - 3, y - 3, w + 6, h + 6);
  230.         }
  231.         old_obj = -1;                                  /* Annuler objet courant */
  232.       }
  233.       /* Si on est sur une option */
  234.       else if ((wind->adr_wmenu)[obj].ob_type == G_STRING)
  235.       {
  236.           if (old_obj != obj)    /* Si objet différent de l'ancien */
  237.         {
  238.             if ((old_obj != -1) && (! ((wind->adr_wmenu)[old_obj].ob_state & DISABLED)))
  239.           { /* S'il y avait un objet courant non inactif */
  240.               /* Le désélectionner */
  241.               etat = (wind->adr_wmenu)[old_obj].ob_state & ~SELECTED;
  242.             objc_change ((wind->adr_wmenu), old_obj, 0, x, y, w, h, etat, 1);
  243.           }
  244.           if ((obj > -1) && (! ((wind->adr_wmenu)[obj].ob_state & DISABLED)))
  245.           { /* Si le nouvel objet n'est pas inactif */
  246.               /* Le sélectionner */
  247.               etat = (wind->adr_wmenu)[obj].ob_state | SELECTED;
  248.             objc_change ((wind->adr_wmenu), obj, 0, x, y, w, h, etat, 1);
  249.           }
  250.           /* Enregistrer option courante */
  251.           old_obj = obj;
  252.         }
  253.       }
  254.         }
  255.   } while (! sortie); /* Tourner jusqu'à un clic */
  256.  
  257.     wmenu_tnormal (wind, tit, 1);
  258.   if ((obj != -1) && (! ((wind->adr_wmenu)[obj].ob_state & DISABLED)))
  259.   {
  260.         (*wind->wmenu)(obj);
  261.       (wind->adr_wmenu)[obj].ob_state &= ~SELECTED;
  262.   }
  263.   else
  264.   {
  265.       if (obj == -1) /* si clic en dehors du menu */
  266.           (wind->adr_wmenu)[old_obj].ob_state &= ~SELECTED;
  267.     }        
  268.     
  269.   /* Débloquer menu normal */
  270.   wind_update (END_MCTRL);
  271.  
  272. }
  273.  
  274. /*************************************************************************/
  275. /*-----------------------------------------------------------------------*
  276.  * Ajoute un ToolBar dans une fenêtre quelconque avec affichage éventuel.*
  277.  *-----------------------------------------------------------------------*/
  278. void AjouteToolBar (int numObj, int toolbar, int mode, void (*wtoolbar)(int opt))
  279. {
  280.     Wind *wind;
  281.     OBJECT *win_toolbar;
  282.     
  283.     wind = ObjListe(numObj);
  284.  
  285.     if (wind != WIND_NULL && toolbar > 0 && wind->adr_wtoolbar == (OBJECT *)NULL)
  286.     {
  287.         /* Récupère l'adresse de l'objet toolbar */
  288.         rsrc_gaddr (R_TREE, toolbar, &win_toolbar);
  289.         /* Fonction de gestion du menu */
  290.         if (wind->adr_wtoolbar = copy_tree(win_toolbar));
  291.         {
  292.             wind->wtoolbar = wtoolbar;
  293.   
  294.             /* Modifier attributs racine ToolBar */
  295.             wind->adr_wtoolbar->ob_state &= ~OUTLINED;                /* Pas Outline */
  296.             wind->adr_wtoolbar->ob_spec.obspec.framesize = 1;    /* Cadre : 1 vers l'extérieur */
  297.             wind->adr_wtoolbar->ob_spec.obspec.textmode = 1;    /* Objet racine opaque */
  298.             wind->Hpos += wind->adr_wtoolbar[ROOT].ob_height;
  299.  
  300.             RecaleWind(wind);
  301.  
  302.             if (mode == REDRAW && wind->handle != BLANK)
  303.                 wind_set(wind->handle, WF_CURRXYWH, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos);
  304.     }
  305.     }
  306. }
  307.  
  308. /*-----------------------------------------------------------------------*
  309.  * Enlève un ToolBar dans une fenêtre quelconque avec affichage éventuel.*
  310.  *-----------------------------------------------------------------------*/
  311. void EnleveToolBar (int numObj, int mode)
  312. {
  313.     Wind *wind;
  314.     
  315.     wind = ObjListe(numObj);
  316.  
  317.     if (wind != WIND_NULL && wind->adr_wtoolbar != (OBJECT *)NULL)
  318.     {
  319.         if (wind->type == WTYPFORM)
  320.             wind->Hpos -= wind->adr_wtoolbar[ROOT].ob_height;
  321.  
  322.         free(wind->adr_wtoolbar);
  323.         wind->adr_wtoolbar = (OBJECT *)NULL;
  324.         wind->wtoolbar = (void *)NULL;
  325.  
  326.         RecaleWind (wind);
  327.  
  328.         if (mode == REDRAW && wind->handle != BLANK)
  329.         {
  330.             wind_set(wind->handle, WF_CURRXYWH, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos);
  331.             EnvoiRedraw(wind->handle, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos);
  332.         }
  333.     }
  334. }
  335.  
  336. /*-----------------------------------------------------------------------*
  337.  * Cette fonction permet de repositionner les objets Menu et Toolbar qui *
  338.  * peuvent se trouver dans une fenêtre Wind.                             *
  339.  *-----------------------------------------------------------------------*/
  340. void RecaleWind (Wind *wind)
  341. {
  342.     int wx, wy, ww, wh;
  343.     WindForm *ptr_obj;
  344.     
  345.     wind_calc(WC_WORK, wind->attrib, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos, &wx, &wy, &ww, &wh);
  346.     if (wind->type == WTYPFORM)
  347.     {
  348.         ptr_obj = wind->cont.dialog;
  349.         ptr_obj->adr_form->ob_x = wx + ptr_obj->offset;
  350.         ptr_obj->adr_form->ob_y = wy + ptr_obj->offset;
  351.     }
  352.  
  353.     if (wind->adr_wmenu != (OBJECT *)NULL)
  354.     {
  355.         wind->adr_wmenu->ob_x = wx;
  356.         wind->adr_wmenu->ob_y = wy;
  357.         if (wind->type == WTYPFORM)
  358.         {
  359.             ptr_obj->adr_form->ob_y += wind->adr_wmenu[BARTITLE].ob_height + 2;
  360.             wind->adr_wmenu->ob_y += ptr_obj->offset;
  361.         }
  362.     }
  363.     if (wind->adr_wtoolbar != (OBJECT *)NULL)
  364.     {
  365.         if (wind->type == WTYPFORM)
  366.             ptr_obj->adr_form->ob_y += wind->adr_wtoolbar->ob_height + 2;
  367.         wind->adr_wtoolbar->ob_x = wx;
  368.         wind->adr_wtoolbar->ob_y = wy;
  369.         wind->adr_wtoolbar->ob_width = ww;        /* NEW */
  370.  
  371.         if (wind->adr_wmenu != (OBJECT *)NULL)
  372.         {
  373.             wind->adr_wtoolbar->ob_y += wind->adr_wmenu[BARTITLE].ob_height + 1;
  374.             if (wind->type == WTYPFORM || global[1] == 1)
  375.                 wind->adr_wtoolbar->ob_y ++;
  376.         }
  377.         else if (wind->type == WTYPFORM)
  378.             ptr_obj->adr_form->ob_y -= 2;
  379.     }
  380.     if (wind->type == WTYPFORM && wind->adr_wmenu != (OBJECT *)NULL && wind->adr_wtoolbar != (OBJECT *)NULL)
  381.         ptr_obj->adr_form->ob_y -= 2;
  382.     if (wind->type == WTYPFORM && wind->adr_wmenu != (OBJECT *)NULL && wind->adr_wtoolbar == (OBJECT *)NULL && global[1] == 1)
  383.         ptr_obj->adr_form->ob_y++;
  384.         
  385. }
  386.  
  387. /*-----------------------------------------------------------------------*
  388.  * Deselection d'un objet d'une ToolBar                                  *
  389.  *                                                                       *
  390.  * arbre     : Numero de l'arbre d'objets                                  *
  391.  * numObjc : Numero de l'objet                                           *
  392.  *-----------------------------------------------------------------------*/
  393. void ToolBarUnselect(int arbre, int numObjc, int mode)
  394. {
  395.     Wind *wind;
  396.     
  397.     /* On recupere les info sur l'arbre d'objet */
  398.     wind = ObjListe(arbre);
  399.     if (wind != WIND_NULL && wind->adr_wtoolbar != (OBJECT *)NULL)
  400.         objc_change(wind->adr_wtoolbar, numObjc, 0, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos, 0, mode);
  401.  
  402. }
  403. /*-----------------------------------------------------------------------*
  404.  * Selection d'un objet d'une ToolBar                                    *
  405.  *                                                                       *
  406.  * arbre     : Numero de l'arbre d'objets                                  *
  407.  * numObjc : Numero de l'objet                                           *
  408.  *-----------------------------------------------------------------------*/
  409. void ToolBarSelect(int arbre, int numObjc, int mode)
  410. {
  411.     Wind *wind;
  412.     
  413.     /* On recupere les info sur l'arbre d'objet */
  414.     wind = ObjListe(arbre);
  415.     if (wind != WIND_NULL && wind->adr_wtoolbar != (OBJECT *)NULL)
  416.         objc_change(wind->adr_wtoolbar, numObjc, 0, wind->Xpos, wind->Ypos, wind->Wpos, wind->Hpos, 1, mode);
  417.  
  418. }
  419. /**************************-=< Fin du module >=-**************************/
  420.